package com.fingard.dsp.bank.directbank.epay01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.helpers.SeqSingleInfo;
import com.fingard.dsp.bank.helpers.SeqSingleInfoHelper;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;

import java.io.File;
import java.math.BigDecimal;
import java.util.Date;

public class EPAY01SinglePay extends EPAY01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpDetail = new RetAtsSglDetail();
        if ("190803".equals(p_req1908.reqHeader.commandCode)) {
            tmpDetail = d_190803(p_req1908);
        } else if ("190802".equals(p_req1908.reqHeader.commandCode)) {
            tmpDetail = d_190802(p_req1908);
        }
        retAts.writeRetDetail(tmpDetail);
        return retAts;
    }

    public RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;

        try {
            JSONObject bizContent = new JSONObject();
            bizContent.put("businessDocumentCode", p_req1908.singleDetail.askNumber);
            bizContent.put("businessId", p_req1908.singleDetail.askNumber);
            bizContent.put("businessType", "0001");
            bizContent.put("businessSubType", "");
            bizContent.put("tradeType", "0014");
            bizContent.put("thirdPartType", "00");
            bizContent.put("bankCode", p_req1908.singleDetail.recBankCode);
            bizContent.put("bankName", p_req1908.singleDetail.attribute12);
            bizContent.put("bankAreaCode", p_req1908.singleDetail.attribute13);
            bizContent.put("bankAreaName", p_req1908.singleDetail.attribute14);
            bizContent.put("bankLocationCode", "");
            bizContent.put("bankLocationName", "");
            bizContent.put("currencyType", "156");
            bizContent.put("certificateType", "01");
            bizContent.put("certificateCode", p_req1908.singleDetail.certNum);

            String cardType = "01";
            if (StringHelper.hasAnyChar(p_req1908.singleDetail.cardType)) {
                if ("2".equals(p_req1908.singleDetail.cardType)) {
                    cardType = "01";
                } else if ("1".equals(p_req1908.singleDetail.cardType)) {
                    cardType = "02";
                } else {
                    cardType = "03";
                }
            }
            bizContent.put("cardBookType", cardType);
            bizContent.put("cardBookCode", p_req1908.singleDetail.recAct);
            bizContent.put("cardHolder", p_req1908.singleDetail.recName);
            bizContent.put("customerMobile", "");
            String isPrivate = "1";
            if (!"1".equals(p_req1908.singleDetail.isPrivate)) {
                isPrivate = "2";
            }
            bizContent.put("isPrivate", isPrivate);
            bizContent.put("money", p_req1908.singleDetail.payAmount);
            bizContent.put("tradeName", p_req1908.singleDetail.memo);
            bizContent.put("businessRemark", p_req1908.singleDetail.useType);
            bizContent.put("deptCode", "");
            bizContent.put("tradeAdd", "");
            bizContent.put("channelCode", "");
            bizContent.put("subChannelCode", "");
            bizContent.put("companyAccount", p_req1908.singleDetail.payAct);

            JSONObject tmpJsonRequest = new JSONObject();

            tmpJsonRequest.put("platformType", "CUSTOMER_SERVICE");
            tmpJsonRequest.put("systemType", "GH");
            tmpJsonRequest.put("msgTopic", getBankConfig().getSetValue("topic", "", "trans"));
            tmpJsonRequest.put("msgTag", "ATS");
            tmpJsonRequest.put("msgKey", p_req1908.singleDetail.askNumber);
            tmpJsonRequest.put("msgContent", bizContent);

            String tmpStrReq = JSON.toJSONString(tmpJsonRequest);

            String tmpStrRet = sendDataToBank(tmpStrReq);

            if (StringHelper.hasAnyChar(tmpStrRet)) {
                JSONObject tmpJsonResp = JSON.parseObject(tmpStrRet);

                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpJsonResp.getString("resultMessage");
                String tmpRespCode = tmpJsonResp.getString("resultCode");
                tmpRetDetail.transState = "0" + tmpRespCode;
                tmpRetDetail.payInfoCode = "0" + tmpRespCode;
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "银行响应为空,请联系银行处理!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return tmpRetDetail;
    }

    public RetAtsSglDetail d_190803(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
        SeqSingleInfoHelper seqSingHelper = null;
        try {
            seqSingHelper = new SeqSingleInfoHelper(p_req1908.reqHeader.tenant, p_req1908.reqHeader.getBusTime(new Date()));
            SeqSingleInfo singleInfo = new SeqSingleInfo();
            singleInfo.loadFromReqBat(p_req1908);
            JSONObject bizContent = new JSONObject();
            bizContent.put("businessId", p_req1908.singleDetail.askNumber);
            bizContent.put("businessDocumentCode", p_req1908.singleDetail.attribute13);
            bizContent.put("businessType", "ATS");
            bizContent.put("businessSubType", p_req1908.singleDetail.attribute17);
            singleInfo.askNumber = p_req1908.singleDetail.askNumber;
            singleInfo.businessDocumentCode = p_req1908.singleDetail.attribute13;

            String cardBookCode = p_req1908.singleDetail.recAct;
            if (p_req1908.reqHeader.isBatRec) {
                cardBookCode = p_req1908.singleDetail.payAct;
            }
            //companyAccount,公司账号,0004取报文RecAct节点，根据公司账号查找第三方通道，若数据库没有配置，则通过router在找一遍
            String companyAccount = p_req1908.singleDetail.payAct;
            if (p_req1908.reqHeader.isBatRec) {
                companyAccount = p_req1908.singleDetail.recAct;
            }

            String tradeType = "0014";
            if (p_req1908.reqHeader.isBatRec) {
                tradeType = "0013";
            }
            bizContent.put("tradeType", tradeType);

            String thirdPartType = "";
            if ("0".equals(p_req1908.singleDetail.attribute18)) {
                thirdPartType = getBankConfig().getMapValueByKey("thirdPartType", companyAccount);
            } else {
                thirdPartType = getBankConfig().getMapValueByKey("thirdPartType", p_req1908.singleDetail.attribute18);
            }
            bizContent.put("thirdPartType", thirdPartType);
            singleInfo.thirdPartType = thirdPartType;
            String bankCode = p_req1908.singleDetail.recBankCode;
            if (p_req1908.reqHeader.isBatRec) {
                bankCode = p_req1908.singleDetail.payBankCode;
            }

            String FinalBankCode = getBankConfig().getMapValueByKey("BankCodeMapping", bankCode);
            if (FinalBankCode != "" || !FinalBankCode.isEmpty()) {
                bankCode = FinalBankCode;
            }

            bizContent.put("bankCode", bankCode);
            bizContent.put("bankName", p_req1908.singleDetail.recBankName);
            bizContent.put("bankAreaCode", p_req1908.singleDetail.recArea);
            bizContent.put("bankAreaName", p_req1908.singleDetail.recAreaName);
            bizContent.put("bankLocationCode", p_req1908.singleDetail.cnapsCode);
            bizContent.put("bankLocationName", p_req1908.singleDetail.recBankLocation);
            bizContent.put("certificateCode", p_req1908.singleDetail.certNum);
            if (p_req1908.reqHeader.isBatRec) {
                bizContent.put("bankName", p_req1908.singleDetail.payBankName);
                bizContent.put("bankAreaCode", p_req1908.singleDetail.payArea);
                bizContent.put("bankAreaName", p_req1908.singleDetail.payAreaName);
                bizContent.put("bankLocationCode", p_req1908.singleDetail.cnapsCode);
                bizContent.put("bankLocationName", p_req1908.singleDetail.payBankLocation);
            }
            bizContent.put("currencyType", "156");
            bizContent.put("certificateType", "01");
            bizContent.put("certificateCode", p_req1908.singleDetail.certNum);

            String cardType = "01";
            if (StringHelper.hasAnyChar(p_req1908.singleDetail.cardType)) {
                if ("2".equals(p_req1908.singleDetail.cardType)) {
                    cardType = "01";
                } else if ("1".equals(p_req1908.singleDetail.cardType)) {
                    cardType = "02";
                } else {
                    cardType = "03";
                }
            }
            bizContent.put("cardBookType", cardType);
            bizContent.put("cardBookCode", cardBookCode);
            singleInfo.cardBookCode = cardBookCode;
            String cardHolder = p_req1908.singleDetail.recName;
            if (p_req1908.reqHeader.isBatRec) {
                cardHolder = p_req1908.singleDetail.payName;
            }
            bizContent.put("cardHolder", cardHolder);
            singleInfo.cardHolder = cardHolder;
            bizContent.put("customerMobile", "");
            String isPrivate = "1";
            if (!"1".equals(p_req1908.singleDetail.isPrivate)) {
                isPrivate = "2";
            }
            bizContent.put("isPrivate", isPrivate);
            bizContent.put("money", p_req1908.singleDetail.payAmount);
            singleInfo.money = new BigDecimal(p_req1908.singleDetail.payAmount);
            bizContent.put("tradeName", "");
            bizContent.put("businessRemark", p_req1908.singleDetail.memo);
            bizContent.put("deptCode", p_req1908.singleDetail.attribute16);
            bizContent.put("tradeAdd", "");
            bizContent.put("channelCode", p_req1908.singleDetail.attribute14);
            bizContent.put("subChannelCode", p_req1908.singleDetail.attribute15);
            singleInfo.subChannelCode = p_req1908.singleDetail.attribute15;
            bizContent.put("companyAccount", companyAccount);
            singleInfo.companyAccount = companyAccount;
            JSONObject tmpJsonRequest = new JSONObject();
            tmpJsonRequest.put("msgTopic", getBankConfig().getSetValue("topic", "", "trans"));
            tmpJsonRequest.put("msgTag", "ATS");
            tmpJsonRequest.put("platformType", "FMS");
            tmpJsonRequest.put("msgKey", "ATS" + "_" + p_req1908.singleDetail.askNumber);
            tmpJsonRequest.put("msgContent", bizContent);
            tmpJsonRequest.put("systemType", "GH");

            try {
                seqSingHelper.insertSeqSingleInfo(singleInfo);
            } catch (Exception ex) {
                this.WriteBankLogLn(ex);
                tmpRetDetail.respInfo = "保存交易信息于DB出现异常，不继续执行报文发送，异常信息：" + LogHelper.getStackTraceFirstLine(ex);
                tmpRetDetail.respCode = "0";
                tmpRetDetail.transState = PaymentState.FAIL;
                tmpRetDetail.payInfoCode = "E9999";
                return tmpRetDetail;
            }
            String tmpStrReq = JSON.toJSONString(tmpJsonRequest);
            sendDataToBank(tmpStrReq);
            tmpRetDetail.respCode = "0";
            tmpRetDetail.respInfo = "批次提交成功";
            tmpRetDetail.transState = "I4001";
            tmpRetDetail.payInfoCode = "I4001";
            singleInfo.payState = tmpRetDetail.transState;
            singleInfo.payInfoCode = tmpRetDetail.payInfoCode;
            seqSingHelper.updateTransState(singleInfo);
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        } finally {
            if (seqSingHelper != null) {
                seqSingHelper.close();
            }
        }
        return tmpRetDetail;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        if ("190803".equals(p_req1944.reqHeader.commandCode)) {
            return d_QrySgl_190803(p_req1944);
        } else {
            return d_QrySgl_190802(p_req1944);
        }
    }

    public RetAtsSingle d_QrySgl_190802(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1944.askNumber;

        try {
            String localFilePath = StringHelper.trimEnd(bankFront.bkTransFolder, File.separator) + File.separator + p_req1944.askNumber + ".txt";
            WriteBankLogLn("本机交易通知结果文件路径:" + localFilePath);
            File tmpLocalFile = new File(localFilePath);
            if (tmpLocalFile.exists()) {
                String tmpStrRet = FileHelper.readFileText(localFilePath, getCharset());
                WriteBankLogLn("本机通知结果文件内容:\r\n" + tmpStrRet);

                JSONArray tmpRespArray = JSONArray.parseArray(tmpStrRet);
                JSONObject tmpRespJson = tmpRespArray.getJSONObject(0);

                tmpRetDetail.respCode = "0";
                String tmpRespInfo = tmpRespJson.getString("errorMessage");
                if (StringHelper.hasAnyChar(tmpRespInfo)) {
                    tmpRetDetail.respInfo = tmpRespInfo;
                }
                tmpRetDetail.transState = tmpRespJson.getString("tradeState");
                tmpRetDetail.payInfoCode = tmpRespJson.getString("errorCode");
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "本机通知结果文件不存在,请稍后查询!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingle d_QrySgl_190803(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1944.askNumber;

        SeqSingleInfoHelper seqSingHelper = null;
        try {
            seqSingHelper = new SeqSingleInfoHelper(p_req1944.reqHeader.tenant, p_req1944.reqHeader.getBusTime(new Date()));
            SeqSingleInfo singleInfo = seqSingHelper.loadFromDb(p_req1944.reqHeader.bankCode, p_req1944.askNumber);

            if (singleInfo == null) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "查不到该交易的提交记录，请在未知状态下重发代收付指令";
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }
            tmpRetDetail.reqSeqID = singleInfo.askNumber;
            tmpRetDetail.transAmt = singleInfo.money.toString();
            tmpRetDetail.transState = singleInfo.payState;
            tmpRetDetail.payInfoCode = singleInfo.payInfoCode;
            tmpRetDetail.respInfo = singleInfo.payInfo;
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        } finally {
            if (seqSingHelper != null) {
                seqSingHelper.close();
            }
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}